package org.jeecg.access.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.access.constant.PlatformType;
import org.jeecg.access.entity.PlatformAccount;
import org.jeecg.access.platform.entity.BaseUserInfo;
import org.jeecg.access.platform.entity.BaseWorkData;
import org.jeecg.access.platform.entity.DyUserInfo;
import org.jeecg.access.platform.entity.DyWorksData;
import org.jeecg.access.platform.mapper.DyUserInfoMapper;
import org.jeecg.access.platform.mapper.DyWorksDataMapper;
import org.jeecg.access.platform.service.PlatformHandler;
import org.jeecg.access.platform.util.HttpRequestUtil;
import org.jeecg.access.platform.util.JsonParserUtils;
import org.jeecg.access.service.PlatformAccountService;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.util.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 抖音数据获取服务实现类
 * 统一使用JsonParserUtils解析JSON，移除Map反序列化和ApiDataUtil依赖
 */
@Slf4j
@Service
public class DyGetDataServiceImpl extends AbstractGetDataServiceImpl implements PlatformHandler {

    private final DyUserInfoMapper userInfoMapper;
    private final DyWorksDataMapper worksDataMapper;

    private final PlatformAccountService platformAccountService;

    @Value("${more.token}")
    private String token;
    @Value("${more.dy.userDetail}")
    private String userDetailUrl;
    @Value("${more.dy.userPost}")
    private String userPostUrl;

    @Autowired
    public DyGetDataServiceImpl(
            DyUserInfoMapper userInfoMapper,
            DyWorksDataMapper worksDataMapper,
            HttpRequestUtil httpRequestUtil,
            ObjectMapper objectMapper,
            PlatformAccountService platformAccountService
    ) {
        super(httpRequestUtil, objectMapper);
        this.userInfoMapper = userInfoMapper;
        this.worksDataMapper = worksDataMapper;
        this.platformAccountService = platformAccountService;
    }

    // ========================== 用户信息同步实现 ==========================

    @Override
    protected List<? extends BaseUserInfo> fetchUserInfoList() {
        List<DyUserInfo> userInfos = userInfoMapper.getUserInfos();
        return userInfos != null ? userInfos : new ArrayList<>();
    }

    @Override
    protected Map<String, String> createUserRequestHeaders(BaseUserInfo user) {
        Map<String, String> headers = new HashMap<>(2);
        headers.put("Content-Type", "application/json");
        headers.put("Authorization", token);
        return headers;
    }

    @Override
    protected String buildUserRequestData(BaseUserInfo user) {
        if (!(user instanceof DyUserInfo)) {
            log.error("用户类型错误，无法构建请求报文");
            return null;
        }
        DyUserInfo dyUser = (DyUserInfo) user;
        return String.format(
                "{\"sec_user_id\":\"%s\",\"share_text\":\"\",\"proxy\":\"false\"}",
                dyUser.getSecUserId()
        );
    }

    @Override
    protected String getUserApiUrl(BaseUserInfo user) {
        return userDetailUrl;
    }

    @Override
    protected String getUserRequestMethod() {
        return "POST";
    }

    @Override
    protected HttpRequestUtil.RetryDecision createUserRetryDecision(BaseUserInfo user) {
        return new DyUserRetryDecision();
    }

    private class DyUserRetryDecision implements HttpRequestUtil.RetryDecision {
        @Override
        public boolean needRetry(int responseCode, String response) {
            // 1. 响应为空校验
            if (response == null || response.trim().isEmpty()) {
                log.debug("用户请求响应为空，需要重试");
                return true;
            }

            try {
                // 2. 检查业务状态是否成功
                Boolean isBusinessSuccess = JsonParserUtils.isSuccess(response);
                if (isBusinessSuccess == null || !isBusinessSuccess) {
                    log.debug("用户请求业务响应失败，需要重试");
                    return true;
                }

                // 3. 检查核心节点data.user是否有效
                Boolean isUserDataValid = JsonParserUtils.isNodeValid(response, "data.user");
                if (isUserDataValid == null || !isUserDataValid) {
                    log.debug("用户请求核心节点(data.user)无效，需要重试");
                    return true;
                }

            } catch (Exception e) {
                log.error("解析用户响应失败，需要重试", e);
                return true;
            }

            return false;
        }
    }

    @Override
    protected BaseUserInfo parseUserResponse(BaseUserInfo originalUser, String response) {
        if (!(originalUser instanceof DyUserInfo)) {
            log.error("用户类型错误，无法解析响应数据");
            return null;
        }
        DyUserInfo dyUser = (DyUserInfo) originalUser;

        try {
            // 检查data.user节点有效性
            Boolean isUserDataValid = JsonParserUtils.isNodeValid(response, "data.user");
            if (isUserDataValid == null || !isUserDataValid) {
                log.error("用户信息响应缺少data.user节点或节点无效");
                return null;
            }

            // 直接通过路径提取用户信息字段
            dyUser.setName(JsonParserUtils.getStringValueFromString(response, "data.user.nickname"));
            dyUser.setFansCount(JsonParserUtils.getIntValueFromString(response, "data.user.follower_count"));
            dyUser.setFollowingCount(JsonParserUtils.getIntValueFromString(response, "data.user.following_count"));
            dyUser.setMaxFansCount(JsonParserUtils.getIntValueFromString(response, "data.user.max_follower_count"));
            dyUser.setMPlatformFollowCount(JsonParserUtils.getIntValueFromString(response, "data.user.mplatform_followers_count"));
            dyUser.setPraisedCount(JsonParserUtils.getIntValueFromString(response, "data.user.total_favorited"));
            dyUser.setWorksCount(JsonParserUtils.getIntValueFromString(response, "data.user.aweme_count"));

            return dyUser;
        } catch (Exception e) {
            log.error("解析用户信息失败", e);
            return null;
        }
    }

    @Override
    protected void batchUpdateUserInfo(List<? extends BaseUserInfo> userInfos) {
        if (userInfos.isEmpty()) {
            log.info("没有需要更新的抖音用户信息");
            return;
        }

        List<DyUserInfo> dyUsers = new ArrayList<>(userInfos.size());
        for (int i = 0; i < userInfos.size(); i++) {
            BaseUserInfo user = userInfos.get(i);
            if (user instanceof DyUserInfo) {
                dyUsers.add((DyUserInfo) user);
            } else {
                log.warn("跳过非抖音用户类型的数据，索引：{}", i);
            }
        }

        if (!dyUsers.isEmpty()) {
            userInfoMapper.batchUpSert(dyUsers);
            log.info("批量更新抖音用户信息完成，共 {} 条", dyUsers.size());
        }
    }

    // ========================== 作品数据同步实现 ==========================

    @Override
    protected HttpRequestUtil.RetryDecision createWorkRetryDecision(BaseWorkData workData) {
        return new DyWorkRetryDecision();
    }

    private class DyWorkRetryDecision implements HttpRequestUtil.RetryDecision {
        @Override
        public boolean needRetry(int responseCode, String response) {
            // 1. HTTP状态码校验（5xx错误重试）
            if (responseCode >= 500 && responseCode < 600) {
                log.debug("作品请求HTTP 5xx错误({})，需要重试", responseCode);
                return true;
            }

            // 2. 响应为空校验
            if (response == null || response.trim().isEmpty()) {
                log.debug("作品请求响应为空，需要重试");
                return true;
            }

            try {
                // 3. 检查业务状态是否成功
                Boolean isBusinessSuccess = JsonParserUtils.isSuccess(response);
                if (isBusinessSuccess == null || !isBusinessSuccess) {
                    log.debug("作品请求业务响应失败，需要重试");
                    return true;
                }

                // 4. 检查data.aweme_list是否为非空数组
                Integer listLength = JsonParserUtils.getListLength(response, "data.aweme_list");
                if (listLength == null || listLength <= 0) {
                    log.debug("作品请求核心节点(data.aweme_list)无效或为空，需要重试");
                    return true;
                }
            } catch (Exception e) {
                log.error("解析作品响应失败，需要重试", e);
                return true;
            }

            return false;
        }
    }

    @Override
    protected List<? extends BaseWorkData> fetchUserAllWorks(BaseUserInfo userInfo, String nowTime,Integer dataNum) throws Exception {
        if (!(userInfo instanceof DyUserInfo)) {
            log.error("用户类型错误，无法获取抖音作品");
            return new ArrayList<>();
        }
        DyUserInfo dyUser = (DyUserInfo) userInfo;
        Map<String, String> headers = createHeaders(userInfo);

        return fetchUserWorks(dyUser, headers, nowTime);
    }


    @Override
    protected void batchUpdateWorksData(List<? extends BaseWorkData> worksData) {
        if (worksData.isEmpty()) {
            log.info("没有需要更新的抖音作品数据");
            return;
        }

        List<DyWorksData> dyWorks = new ArrayList<>(worksData.size());
        for (int i = 0; i < worksData.size(); i++) {
            BaseWorkData work = worksData.get(i);
            if (work instanceof DyWorksData) {
                dyWorks.add((DyWorksData) work);
            } else {
                log.warn("跳过非抖音作品类型的数据，索引：{}", i);
            }
        }

        if (!dyWorks.isEmpty()) {
            worksDataMapper.batchUpSert(dyWorks);
            log.info("批量更新抖音作品数据完成，共 {} 条", dyWorks.size());
        }
    }

    @Override
    protected Map<String, String> createHeaders(BaseUserInfo userInfo) {
        Map<String, String> headers = new HashMap<>(2);
        headers.put("Content-Type", "application/json");
        headers.put("Authorization", token);
        return headers;
    }

    // ========================== 自定义业务方法（使用JsonParserUtils优化） ==========================

    /**
     * 获取用户作品列表（完全基于JsonParserUtils解析）
     */
    private List<DyWorksData> fetchUserWorks(DyUserInfo userInfo, Map<String, String> headers, String nowTime) throws IOException {
        String secUserId = userInfo.getSecUserId();
        if (secUserId == null || secUserId.isEmpty()) {
            log.warn("用户sec_user_id为空，无法获取作品");
            return new ArrayList<>();
        }

        Map<String, Object> requestMap = new HashMap<>(6);
        requestMap.put("sec_user_id", secUserId);
        requestMap.put("share_text", "");
        requestMap.put("count", userInfo.getWorksCount() > 0 ? userInfo.getWorksCount() : 20);
        requestMap.put("max_cursor", "");
        requestMap.put("filter_type", "");
        requestMap.put("proxy", "false");

        String requestBody;
        try {
            requestBody = objectMapper.writeValueAsString(requestMap);
        } catch (JsonProcessingException e) {
            throw new IOException("序列化作品请求参数失败", e);
        }

        // 发送请求并获取响应
        String response = httpRequestUtil.sendRequest(
                userPostUrl,
                "POST",
                headers,
                requestBody,
                createWorkRetryDecision(new DyWorksData())
        );

        if (response == null || response.trim().isEmpty()) {
            log.warn("获取用户 {} 作品响应为空", secUserId);
            return new ArrayList<>();
        }

        // 直接使用响应字符串解析作品列表，移除Map反序列化
        return parseWorksResponse(response, userInfo.getId(), secUserId, nowTime);
    }

    /**
     * 解析作品响应数据（基于JsonParserUtils和路径解析）
     */
    private List<DyWorksData> parseWorksResponse(String response, String userId, String secUserId, String nowTime) {
        List<DyWorksData> worksList = new ArrayList<>();

        try {
            // 检查data.aweme_list是否为有效数组
            Integer listLength = JsonParserUtils.getListLength(response, "data.aweme_list");
            if (listLength == null || listLength <= 0) {
                log.info("抖音用户 {} 没有有效作品数据", secUserId);
                return worksList;
            }

            // 循环解析每个作品（使用索引构建路径）
            for (int i = 0; i < listLength; i++) {
                String basePath = "data.aweme_list[" + i + "]";
                try {
                    // 基础信息解析
                    String awemeId = JsonParserUtils.getStringValueFromString(response, basePath + ".aweme_id");
                    if (awemeId == null || awemeId.isEmpty()) {
                        log.warn("第{}个作品缺少aweme_id，跳过解析", i + 1);
                        continue;
                    }

                    DyWorksData work = new DyWorksData();
                    work.setId(UUIDGenerator.generate());
                    work.setUserId(userId);
                    work.setUpdateTime(nowTime);
                    work.setAwemeId(awemeId);
                    work.setDescription(JsonParserUtils.getStringValueFromString(response, basePath + ".desc"));
                    work.setTitle(JsonParserUtils.getStringValueFromString(response, basePath + ".item_title"));

                    // 统计信息解析（嵌套路径）
                    work.setDownloadCount(JsonParserUtils.getIntValueFromString(response, basePath + ".statistics.download_count"));
                    work.setCollectCount(JsonParserUtils.getIntValueFromString(response, basePath + ".statistics.collect_count"));
                    work.setCommentCount(JsonParserUtils.getIntValueFromString(response, basePath + ".statistics.comment_count"));
                    work.setShareCount(JsonParserUtils.getIntValueFromString(response, basePath + ".statistics.share_count"));
                    work.setDiggCount(JsonParserUtils.getIntValueFromString(response, basePath + ".statistics.digg_count"));

                    // 时长和创建时间解析
                    work.setDuration(JsonParserUtils.getLongValueFromString(response, basePath + ".duration"));
                    Long createTime = JsonParserUtils.getLongValueFromString(response, basePath + ".create_time");
                    if (createTime != null && createTime > 0) {
                        work.setCreateTime(DateTimeUtil.convertTimestampToFormat(createTime));
                    } else {
                        log.warn("作品 {} 的create_time为空或无效", awemeId);
                    }

                    worksList.add(work);
                } catch (Exception e) {
                    log.error("解析第{}个作品数据失败: sec_user_id={}", i + 1, secUserId, e);
                }
            }
        } catch (Exception e) {
            log.error("解析作品列表响应失败: sec_user_id={}", secUserId, e);
        }

        return worksList;
    }

    // ========================== PlatformHandler接口实现（使用JsonParserUtils优化） ==========================

    @Override
    public String getPlatformType() {
        return PlatformType.DY.getCode();
    }

    @Override
    public List<?> fetchExternalData() {
        List<DyUserInfo> localUserList = userInfoMapper.getUserInfos();
        if (localUserList == null) {
            log.warn("本地抖音用户表查询返回null，返回空列表");
            return new ArrayList<>();
        }
        log.info("从本地抖音用户表获取到 {} 条已有数据", localUserList.size());
        return localUserList;
    }

    @Override
    public String extractAccountId(Object data) {
        if (data == null || !(data instanceof DyUserInfo)) {
            log.warn("本地用户数据格式无效，无法提取账号ID");
            return null;
        }
        DyUserInfo localUser = (DyUserInfo) data;
        return localUser.getId();
    }

    /**
     * 校验账号有效性（移除Map解析，使用JsonParserUtils）
     */
    @Override
    public boolean verifyAccount(PlatformAccount account) {
        if (account == null || account.getAccountId() == null || account.getAccountId().trim().isEmpty()) {
            log.warn("待校验账号信息无效（ID为空）");
            return false;
        }

        String secUserId = account.getAccountId().trim();
        DyUserInfo userInfo = new DyUserInfo();
        userInfo.setSecUserId(secUserId);

        Map<String, String> headers = createHeaders(userInfo);

        try {
            String requestBody = buildUserRequestData(userInfo);
            if (requestBody == null) {
                log.error("构建账号校验请求报文失败");
                return false;
            }

            // 发送请求并获取响应
            String response = httpRequestUtil.sendRequest(
                    getUserApiUrl(userInfo),
                    getUserRequestMethod(),
                    headers,
                    requestBody,
                    createUserRetryDecision(userInfo)
            );

            if (response == null || response.trim().isEmpty()) {
                log.warn("账号[{}]校验失败：响应为空", secUserId);
                return false;
            }

            log.info("账号[{}]校验成功：在抖音真实存在", secUserId);
            return true;
        } catch (Exception e) {
            log.error("账号[{}]校验失败：抖音API请求异常", secUserId, e);
            return false;
        }
    }

    @Override
    public void writeToExternalSystem(PlatformAccount account) {
        if (account == null || account.getAccountId() == null || account.getAccountId().trim().isEmpty()) {
            log.warn("待同步账号信息无效（ID为空）");
            return;
        }

        String secUserId = account.getAccountId().trim();
        String nowTime = DateTimeUtil.getCurrentTimestamp();
        DyUserInfo userInfo = new DyUserInfo();

        userInfo.setSecUserId(secUserId);
        userInfo.setCreator(account.getCreator());
        userInfo.setCreateTime(account.getCreateTime());
        userInfo.setUpdater(account.getUpdater());
        userInfo.setUpdateTime(nowTime);
        userInfo.setState(account.getState());
        userInfo.setId(account.getId());

        userInfoMapper.insert(userInfo);
        log.info("账号[{}]已同步到本地抖音用户表", secUserId);
    }

    @Override
    public String verifyAddedAccount(PlatformAccount account) {

        if (null == account.getAccountId() || account.getAccountId().trim().isEmpty()) {
            return "抖音账号的accountId不能为空";
        }

//        if (isEmpty(account.getClientKey())) {
//            return "抖音账号的clientKey不能为空";
//        }
//        if (isEmpty(account.getClientSecret())) {
//            return "抖音账号的clientSecret不能为空";
//        }

        QueryWrapper<PlatformAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("platform_type", account.getPlatformType());
        queryWrapper.eq("account_id", account.getAccountId());
        int count = platformAccountService.count(queryWrapper);
        if (count > 0) {
            return "抖音账号的accountId账号已存在";
        }
        return null;
    }
}
